package com.bbs.dao.impl;

import java.sql.SQLException;
import java.util.List;

import javax.annotation.Resource;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.exception.DataException;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.stereotype.Component;

@Component("hibernatedao")
public class HibernateDAO {

	private HibernateTemplate hibernateTemplate;

	public HibernateTemplate getHibernateTemplate() {
		return hibernateTemplate;
	}

	@Resource
	public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
		this.hibernateTemplate = hibernateTemplate;
	}

	/**
	 * 向数据库添加一条对应于一个业务对象实例的记录
	 * 
	 * @param Object
	 *            业务对象实例
	 */
	public boolean create(Object entity) throws DataException {
		try {
			getHibernateTemplate().save(entity);
			return true;
		} catch (DataAccessException e) {
			return false;
		}
	}

	/**
	 * 使用hql 语句进行操作
	 * 
	 * @param hql
	 *            HSQL 查询语句
	 * @param offset
	 *            开始取数据的下标
	 * @param length
	 *            读取数据记录数
	 * @return List 结果集
	 */
	public List getListForPage(final String hql, final int offset,
			final int length) {

		List list = getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(hql);
				query.setFirstResult(offset);
				query.setMaxResults(length);
				List list = query.list();
				return list;
			}
		});
		return list;
	}

	/**
	 * 根据关键字从数据库加载指定类型的业务对象。
	 * 
	 * @param clazz
	 *            业务对象的Class
	 * @param keyName
	 *            指定关键字对应的字段名称
	 * @param keyValue
	 *            指定关键字的值
	 * @return <ul>
	 *         <li>当关键字唯一并存在该记录时，返回该记录对应的业务对象</li>
	 *         <li>当关键字不唯一，返回查询结果的第一条记录所对应的业务对象</li>
	 *         <li>当不存在该记录时,返回null</li>
	 */
	public Object loadByKey(Class clazz, String keyName, Object keyValue)
			throws DataException {

		List result = getHibernateTemplate().find(
				"from " + clazz.getName() + " where " + keyName + " = ?",
				keyValue);
		if (result != null && result.size() > 0) {
			return result.get(0);
		} else {
			return null;
		}

	}

	/**
	 * 根据Hql语句 和关键字从数据库加载指定类型的业务对象。
	 * 
	 * @param hql
	 *            hql语句
	 * @param keyName
	 *            指定关键字对应的字段名称
	 * @param keyValue
	 *            指定关键字的值
	 * @return <ul>
	 *         <li>当关键字唯一并存在该记录时，返回该记录对应的业务对象</li>
	 *         <li>当不存在该记录时,返回null</li>
	 */
	public Object loadKey(String hql, Object keyValue) throws DataException {

		List result = getHibernateTemplate().find(hql, keyValue);
		if (result != null && result.size() > 0) {
			return result.get(0);
		} else {
			return null;
		}

	}

	/**
	 * 根据已定义的带一个参数的查询语句查询数据库并返回查询结果所包含的业务对象集合。
	 * 
	 * @param queryName
	 *            已定义查询语句的名称
	 * @param param
	 *            指定的参数
	 * @return 返回查询结果包含的业务对象集合
	 */
	public List findByNamedQuery(String queryName, Object param)
			throws DataException {

		return getHibernateTemplate().findByNamedQuery(queryName, param);

	}
}